import * as THREE from '../jsm/three.module.js';
import { OrbitControls } from '../jsm/controls/OrbitControls.js';

import { requestLand } from '../../../../api/server';

import { worker } from './worker.js';

import { landMaterialFunc } from './index';

import { GPSInfo } from '../../requestParent'

// import { testLand } from './testLand';

let container;
let scene, camera, renderer;
let controls;

let animationFrame;

let landMesh; // 河床Mesh对象

let clipMode = false; // 剖面模式

let raycaster; // 射线

let clipClickPoint1, clipClickPoint2;

let maskPlane, colorPlanesGroup;
let shipToken;

function init(mount) {

    container = mount;

    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 10, 3000);
    renderer = new THREE.WebGLRenderer({ antialias: true });

    scene.background = new THREE.Color(0x74B8FC);
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(container.clientWidth, container.clientHeight);
    container.appendChild(renderer.domElement);
    // console.log(container.clientWidth, container.clientHeight);

    controls = new OrbitControls(camera, renderer.domElement);
    controls.maxDistance = 3000;
    // camera.position.set(0, -12, 100);
    // controls.target.set(0, -12, 0);
    // controls.update();

    // controls.enableRotate = false;

    let dirL = new THREE.DirectionalLight(0xffffff, 3);
    dirL.position.set(1, 1, 1)
    scene.add(dirL);

    let ambL = new THREE.AmbientLight(0xffffff, 1);
    scene.add(ambL);

    raycaster = new THREE.Raycaster(); // 创建射线

    // 射线点位球
    let geometry = new THREE.SphereBufferGeometry(1, 16, 16);
    let material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
    clipClickPoint1 = new THREE.Mesh(geometry, material);
    clipClickPoint2 = new THREE.Mesh(geometry, material);
    clipClickPoint1.visible = clipClickPoint2.visible = false;
    scene.add(clipClickPoint1);
    scene.add(clipClickPoint2);

    createShipToken(); // 船的代替物

    createPlaneGroup(); // 创建颜色面组
    createMaskPlane(); // 创建遮罩面

    // let axesHelper = new THREE.AxesHelper(1000);
    // scene.add(axesHelper);

    window.out_scene = scene;
    window.out_controls = controls;

}
// 剖面遮罩对象
function createMaskPlane(params) {
    let shape = new THREE.Shape();

    let x = -25, y = 0;

    shape.moveTo(x, y);
    shape.lineTo(x + 50, y);
    shape.lineTo(x + 50, y - 8);

    shape.lineTo(x + 45, y - 8);
    shape.lineTo(x + 40, y - 14);
    shape.lineTo(x + 39, y - 18);
    shape.lineTo(x + 35, y - 16);
    shape.lineTo(x + 30, y - 9);
    shape.lineTo(x + 21, y - 11);
    shape.lineTo(x + 18, y - 16);
    shape.lineTo(x + 15, y - 10);
    shape.lineTo(x + 14, y - 12);
    shape.lineTo(x + 10, y - 14);
    shape.lineTo(x + 4, y - 13);

    shape.lineTo(x, y - 8);
    shape.lineTo(x, y);

    let geometry = new THREE.ShapeBufferGeometry(shape);
    let material = new THREE.MeshBasicMaterial({ color: 0x74B8FC, depthTest: false });
    maskPlane = new THREE.Mesh(geometry, material);
    maskPlane.visible = false;
    scene.add(maskPlane);
}

// 剖面组
function createPlaneGroup(width = 50) {

    let positionY = 0;

    function createPlane(height, color) {
        let geometry = new THREE.PlaneBufferGeometry(width, height);
        let material = new THREE.MeshBasicMaterial({ color });
        let plane = new THREE.Mesh(geometry, material);
        plane.position.y = positionY - height / 2;
        positionY -= height;
        colorPlanesGroup.add(plane);
    }

    colorPlanesGroup = new THREE.Group();
    colorPlanesGroup.name = '河床面组';
    colorPlanesGroup.visible = false;

    let array = [
        [12, new THREE.Color(0.7176, 0.6588, 0.5686)],
        [1, new THREE.Color(0.6549, 0.5294, 0.3765)],
        [1, new THREE.Color(0.4157, 0.3137, 0.2549)],
        [1, new THREE.Color(0.4863, 0.2471, 0.1765)],
        [1, new THREE.Color(0.2824, 0.1647, 0.1255)],
        [6, new THREE.Color(0.2196, 0.1725, 0.1882)],
    ];

    for (let i = 0, len = array.length; i < len; i++) {
        let element = array[i];
        createPlane(element[0], element[1])
    }

    scene.add(colorPlanesGroup);


}

// 船的代替物
function createShipToken() {
    shipToken = new THREE.Mesh(new THREE.BoxBufferGeometry(5, 5, 5), new THREE.MeshPhongMaterial({ color: 0x0000ff }));
    shipToken.position.set(GPSInfo.position.x, 0, GPSInfo.position.y);
    scene.add(shipToken);
    shipToken.visible = false;

    controls.target.copy(shipToken.position);
    camera.position.copy(controls.target.clone());
    camera.position.y += 80;
    controls.update();

}

// 启用场景
function enableScene() {
    window.addEventListener('resize', onWindowResize, false);
    renderer.domElement.addEventListener('click', onClick, false);
    animate();
}

function animate() {
    animationFrame = requestAnimationFrame(animate);
    renderer.render(scene, camera);
}

function onWindowResize() {
    camera.aspect = container.clientWidth / container.clientHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(container.clientWidth, container.clientHeight);
}

function onClick(event) {
    if (clipMode) {

        let mouse = new THREE.Vector2();
        let rect = renderer.domElement.getBoundingClientRect();

        mouse.x = (event.clientX - rect.left) / rect.width * 2 - 1;
        mouse.y = - (event.clientY - rect.top) / rect.height * 2 + 1;

        // 通过摄像机和鼠标位置更新射线
        raycaster.setFromCamera(mouse, camera);

        // 计算物体和射线的焦点
        // console.log(raycaster.intersectObject(landMesh));

        let intersect = raycaster.intersectObject(landMesh)[0] || false;

        if (intersect) {
            // console.log(intersect);

            if (!clipClickPoint1.visible) {
                clipClickPoint1.position.copy(intersect.point);
                clipClickPoint1.visible = true;
            } else if (!clipClickPoint2.visible) {
                clipClickPoint2.position.copy(intersect.point);
                clipClickPoint2.visible = true;

                worker.postMessage({
                    cmd: 'CuttingSurface',
                    params: {
                        v1: { x: clipClickPoint1.position.x, y: clipClickPoint1.position.y, z: clipClickPoint1.position.z },
                        v2: { x: clipClickPoint2.position.x, y: clipClickPoint2.position.y, z: clipClickPoint2.position.z },
                    },
                });


            }
        }

    }
}

function initLandScene(mount) {
    if (!renderer) {
        init(mount);
        requestDetailLand(); // 请求完整的河床
    } else {
        container = mount;
        container.appendChild(renderer.domElement);
    }
    enableScene();
    setTimeout(onWindowResize, 100); // 用于界面div获取到宽高，延迟处理
}

function stopLandScene(mount) {
    if (animationFrame) cancelAnimationFrame(animationFrame);
    if (renderer) {
        window.removeEventListener('resize', onWindowResize, false);
        renderer.domElement.removeEventListener('click', onClick, false);
        // mount.removeEventListener('click', onMouseClick, false);
    }
}

// worker监听完成计算的回调
function workerOnMessage(data) {
    switch (data.cmd) {
        // 全部土地
        case 'DetailLand':
            if (landMesh) {
                updateLand(data.params);
            } else {
                createLand(data.params);
            }
            break;

        // 计算裁剪面
        case 'CuttingSurface':
            // 土地 剖面球体隐藏
            landMesh.visible = shipToken.visible = clipClickPoint1.visible = clipClickPoint2.visible = false;
            updateCilpPlane(data.params); // 更新剖面
            updateLookAt('剖面'); // 更新视角
            // 剖面显示
            maskPlane.visible = colorPlanesGroup.visible = true;
            break;
        default:
            break;
    };
}

// 加载详细地面
function requestDetailLand() {

    // worker.postMessage({
    //     cmd: 'DetailLand',
    //     params: testLand,
    // });

    // return;S

    requestLand({
        method: 'GetLandDetailData',
        gpsX: GPSInfo.position.x,
        gpsY: GPSInfo.position.y,
        water_depth_file_name: '[7ab8b2c4-4bf0-4352-a2ef-52691677b0e7,08e4fedc-857d-4426-b0c5-6490c8619baa,52d8597d-022e-4a51-afce-226d63c0ac83,97813129-0dc2-4d05-bb11-8b6dbfa712c7,af2c5589-43a0-44c5-9cb2-171ba7a7cd7b,fd357f40-f560-4bb3-b0e3-1f8b64463a50]',
    }).then(function (res) {
        // console.log(res);
        // console.log(JSON.stringify(
        //     [
        //         res.data[4],
        //     ]
        // ));

        worker.postMessage({
            cmd: 'DetailLand',
            params: res.data,
        });
    })
        .catch(err => {
            console.log(err)
        })
}

// 创建地面
function createLand(vertices) {
    let landGeometry = new THREE.BufferGeometry();
    landGeometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
    // landGeometry.attributes.position.usage = THREE.StaticDrawUsage;
    landGeometry.computeVertexNormals(); // 计算法线
    // console.log(landGeometry);

    landMesh = new THREE.Mesh(landGeometry, landMaterialFunc());
    // console.log(landMesh);

    scene.add(landMesh);
}

// 更新地面
function updateLand(vertices) {
    landMesh.geometry.attributes.position.copyArray(vertices);
    landMesh.geometry.attributes.position.needsUpdate = true;
    landMesh.geometry.computeVertexNormals(); // 计算法线
}

// 更新剖面
let planeHeights = [12, 1, 1, 1, 1, 6];
// 更新裁剪面
function updateCilpPlane(data) {

    let width = data[data.length - 1].x;

    // 更新面组中的面几何体
    for (let i = 0; i < colorPlanesGroup.children.length; i++) {
        const plane = colorPlanesGroup.children[i];
        plane.geometry.dispose();
        plane.geometry = new THREE.PlaneBufferGeometry(width, planeHeights[i]);
    }

    // 更新遮罩面
    let shape = new THREE.Shape();

    let x = -width / 2, y = 0;

    shape.moveTo(x, y);
    shape.moveTo(x, y + data[0].y);
    for (let i = 0; i < data.length; i += 2) {
        shape.lineTo(x + data[i].x, y + data[i].y);
    }
    shape.lineTo(x + width, y + data[data.length - 1].y);
    shape.lineTo(x + width, y);
    shape.lineTo(x, y);

    maskPlane.geometry.dispose();
    maskPlane.geometry = new THREE.ShapeBufferGeometry(shape);

}

// 切换模式
function switchMode(mode) {
    if (!landMesh) return;
    if (mode === '三维') {

        if (clipMode) {
            landMesh.visible = shipToken.visible = true;
            maskPlane.visible = colorPlanesGroup.visible = false;
            updateLookAt('三维'); // 切换三维视角
            clipMode = false;
        }

    } else if (mode === '剖面') {
        clipMode = true;
        clipClickPoint1.visible = clipClickPoint2.visible = false;
    }

}

let saveCameraPosition = new THREE.Vector3(),
    saveControlsTarget = new THREE.Vector3();

function updateLookAt(mode) {
    if (mode === '剖面') {
        // 保存三维状态的视角
        saveCameraPosition.copy(camera.position);
        saveControlsTarget.copy(controls.target);

        camera.position.set(0, -12, 100);
        controls.target.set(0, -12, 0);
        controls.enableRotate = false;
        controls.update();
    } else if (mode === '三维') {
        camera.position.copy(saveCameraPosition);
        controls.target.copy(saveControlsTarget);
        controls.enableRotate = true;
        controls.update();
    }
}

window.disposeGEO = () => {
    
    landMesh.geometry.dispose();
    landMesh.geometry = new THREE.BoxGeometry(1,1,1);
}

export {
    scene,
    controls,
    initLandScene,
    stopLandScene,
    workerOnMessage,
    switchMode,
};


// 艏吹管道，也许以后会用上
// let geometry1 = new THREE.TubeGeometry(new THREE.CatmullRomCurve3([
//     new THREE.Vector3(0, 10, 0),
//     new THREE.Vector3(0, 1, 0),
//     new THREE.Vector3(-80, -5, 0),
// ]), 30, 2, 8, false);
// let material1 = new THREE.MeshPhongMaterial({ color: 0x5F6368, side: 2 });
// var mesh = new THREE.Mesh(geometry1, material1);
// scene.add(mesh);
